﻿Class MainWindow 


    Dim timer As New System.Windows.Threading.DispatcherTimer()
    Dim index As Integer
    Dim active As Boolean
    Dim data As List(Of Subtitle)
    Dim dateBegin As Date

    Public Sub LoadFile(ByVal path As String)
        data = New List(Of Subtitle)
        Dim c = IO.File.OpenText(path)
        Dim nextToken = 0
        Dim text As String = Nothing
        Dim startTime As TimeSpan
        Dim endTime As TimeSpan
        Dim maxTime As TimeSpan = TimeSpan.Zero

        While (Not c.EndOfStream)
            Dim s = c.ReadLine()

            Select Case nextToken
                Case 0
                    If Not String.IsNullOrEmpty(s) Then nextToken = 1
                Case 1
                    s = s.Replace(","c, "."c)
                    Dim f = s.IndexOf(" --> ")
                    startTime = TimeSpan.Parse(s.Substring(0, f))
                    endTime = TimeSpan.Parse(s.Substring(f + 5))

                    If endTime < maxTime Then
                        endTime = maxTime
                    End If
                    If startTime > endTime Then
                        Throw New Exception '   endTime = startTime
                    End If
                    maxTime = endTime
                    nextToken = 2
                    text = String.Empty
                Case 2
                    If String.IsNullOrEmpty(s) Then
                        text = text.Replace("<i>", String.Empty).Replace("</i>", String.Empty).Trim()
                        data.Add(New Subtitle(startTime, endTime, text))
                        nextToken = 0
                    Else
                        text += s + ControlChars.CrLf
                    End If
            End Select


        End While

        Slider1.Minimum = 0
        Slider1.Maximum = data.Count - 1
        Start()
    End Sub

    Dim playing As Boolean
    Sub Start()
        Start(0)
    End Sub

 

    Sub Start(ByVal index As Integer)
        timer.Stop()
        playing = True
        Me.dateBegin = Now - data(index).timeStart
        Me.index = 0
        Me.active = False
        Timer_Tick()
        UpdatePlayButtonText()
    End Sub

    Sub Start(ByVal position As TimeSpan)
        timer.Stop()
        playing = True
        Dim f = data.FindLastIndex(Function(s) s.timeStart <= position)
        If f = -1 Then
            [Stop]()
            Return
        End If
        index = f
        Me.dateBegin = Now - position
        If position < data(f).endTime Then
            active = True
            ApplySubtitle()
        Else
            active = False
            ApplySubtitle()
        End If
        Me.active = False
        Timer_Tick()
        UpdatePlayButtonText()
    End Sub

    Public Sub Timer_Tick()
        timer.Stop()
        active = Not active
        ApplySubtitle()
        Dim nextEvent As TimeSpan
        If active Then
            nextEvent = data(index).endTime - (Now - dateBegin)
        Else
            If index = data.Count - 1 Then
                [Stop]()
                Return
            Else
                nextEvent = data(index + 1).timeStart - (Now - dateBegin)
                index += 1
            End If
        End If

        If nextEvent <= TimeSpan.Zero Then
            Timer_Tick()
        Else
            timer.Interval = nextEvent ' TimeSpan.FromTicks(nextEvent.Ticks / 3)
            timer.Start()
        End If
      

    End Sub



    Sub [Stop]()
        timer.Stop()
        playing = False
        UpdatePlayButtonText()
    End Sub

    Sub [Resume]()
        timer.Start()
        playing = True
        UpdatePlayButtonText()
    End Sub

    Private Sub UpdatePlayButtonText()
        btnPlay.Content = If(playing, "Pause", "Play")
    End Sub


    Private changingSliderValue As Boolean = False
    Private Sub Slider1_ValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.RoutedPropertyChangedEventArgs(Of System.Double)) Handles Slider1.ValueChanged
        If changingSliderValue Then Return
        Start(e.NewValue)
    End Sub

    Sub ApplySubtitle()
        Dim subt = data(index)
        changingSliderValue = True
        Slider1.Value = index
        changingSliderValue = False
        'subtitle.Inlines.Clear()
        If active Then
            TextBlock1.Text = data(index).text
            '     subtitle.Inlines.Add(New Run(data(index).text))
        Else
            TextBlock1.Text = String.Empty
        End If
    End Sub




    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        Dim a = Environment.GetCommandLineArgs()
        Dim path = Nothing
        If a.Length = 2 Then path = a(1)

        If path Is Nothing Then
            Dim f = New Microsoft.Win32.OpenFileDialog
            f.Filter = "Subtitles|*.srt"
            f.ShowDialog()
            path = If(String.IsNullOrEmpty(f.FileName), Nothing, f.FileName)
        End If

        If path Is Nothing Then
            My.Application.Shutdown()
            Return
        End If

        AddHandler timer.Tick, AddressOf Timer_Tick
        LoadFile(path)
        TextBlock1.FontSize = Slider2.Value
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click

    End Sub

    Private Sub btnPlay_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnPlay.Click
        If playing Then
            [Stop]()
        Else
            [Resume]()
        End If
    End Sub

    Private Sub btnForward_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnForward.Click
        Start((Now - dateBegin).Add(TimeSpan.FromMilliseconds(333)))
    End Sub

    Private Sub btnBack_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnBack.Click
        Start((Now - dateBegin).Add(TimeSpan.FromMilliseconds(-333)))

    End Sub



    Private Sub Slider2_ValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.RoutedPropertyChangedEventArgs(Of System.Double)) Handles Slider2.ValueChanged
        TextBlock1.FontSize = e.NewValue

        ' Me.MinWidth = e.NewValue * 20
    End Sub

    Private Sub controls_MouseEnter(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseEventArgs)
        controls.Opacity = 1
    End Sub

    Private Sub controls_MouseLeave(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseEventArgs)
        controls.Opacity = 0.2
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnClose.Click
        Me.Close()
    End Sub

    'Private Sub TextBlock1_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles TextBlock1.SelectionChanged
    '    If TextBlock1.Selection.IsEmpty Then Return
    '    Dim txt = TextBlock1.Selection.Text
    '    definitions.Children.Add(New TextBlock())
    'End Sub

    Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnSearch.Click
        btnSearch.Visibility = Windows.Visibility.Collapsed
        InstantFind.Visibility = Windows.Visibility.Visible
        InstantFind.Focus()
    End Sub

    Private Sub InstantFind_TextChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.TextChangedEventArgs) Handles InstantFind.TextChanged
        Dim f = data.FindIndex(Function(s) s.text.ToLower.Contains(InstantFind.Text.ToLower))
        If f = -1 Then
            My.Computer.Audio.PlaySystemSound(System.Media.SystemSounds.Beep)
        Else
            Start(f)
        End If

    End Sub

    Private Sub InstantFind_LostFocus(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles InstantFind.LostFocus
        InstantFind.Visibility = Windows.Visibility.Collapsed
        btnSearch.Visibility = Windows.Visibility.Visible
    End Sub

    Private Sub Window_StateChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.StateChanged
        If Me.WindowState = Windows.WindowState.Maximized Then Me.WindowState = Windows.WindowState.Normal
    End Sub

End Class
